package common

import (
	"context"
	"log"
	"time"

	"golang.org/x/time/rate"
)

// 🔥 流量控制 - 防止大文件占满带宽

// RateLimiter 速率限制器
// 使用令牌桶算法限制数据传输速率
type RateLimiter struct {
	name              string        // 限制器名称（用于日志）
	maxBytesPerSecond int64         // 最大速率（字节/秒）
	limiter           *rate.Limiter // golang.org/x/time/rate令牌桶
	enabled           bool          // 是否启用限速
}

// NewRateLimiter 创建速率限制器
//
// 参数：
//   - name: 限制器名称（用于日志标识）
//   - maxBytesPerSecond: 最大速率（字节/秒），0表示不限速
//
// 返回：
//   - *RateLimiter: 速率限制器实例
func NewRateLimiter(name string, maxBytesPerSecond int64) *RateLimiter {
	if maxBytesPerSecond <= 0 {
		// 不限速
		return &RateLimiter{
			name:              name,
			maxBytesPerSecond: 0,
			enabled:           false,
		}
	}

	// 创建令牌桶
	// rate: 每秒产生的令牌数
	// burst: 桶的容量（允许短时爆发）
	limiter := rate.NewLimiter(rate.Limit(maxBytesPerSecond), int(maxBytesPerSecond))

	log.Printf("🚦 创建速率限制器: %s, 限速=%d bytes/s (%.2f MB/s)",
		name, maxBytesPerSecond, float64(maxBytesPerSecond)/(1024*1024))

	return &RateLimiter{
		name:              name,
		maxBytesPerSecond: maxBytesPerSecond,
		limiter:           limiter,
		enabled:           true,
	}
}

// WaitForBytes 等待指定数量的字节令牌
//
// 参数：
//   - n: 需要的字节数
//
// 返回：
//   - error: 等待错误（通常是context被取消）
//
// 功能：
//   - 如果未启用限速，立即返回
//   - 否则等待足够的令牌可用
//   - 使用背景context，永不超时
func (rl *RateLimiter) WaitForBytes(n int) error {
	if !rl.enabled || n <= 0 {
		return nil // 不限速或无需等待
	}

	// 等待令牌
	return rl.limiter.WaitN(context.Background(), n)
}

// WaitForBytesWithTimeout 等待指定数量的字节令牌（带超时）
//
// 参数：
//   - n: 需要的字节数
//   - timeout: 超时时间
//
// 返回：
//   - error: 等待错误或超时
func (rl *RateLimiter) WaitForBytesWithTimeout(n int, timeout time.Duration) error {
	if !rl.enabled || n <= 0 {
		return nil
	}

	ctx, cancel := context.WithTimeout(context.Background(), timeout)
	defer cancel()

	return rl.limiter.WaitN(ctx, n)
}

// TryConsume 尝试立即消费指定数量的字节令牌（非阻塞）
//
// 参数：
//   - n: 需要的字节数
//
// 返回：
//   - bool: 是否成功消费令牌
func (rl *RateLimiter) TryConsume(n int) bool {
	if !rl.enabled || n <= 0 {
		return true
	}

	return rl.limiter.AllowN(time.Now(), n)
}

// GetCurrentRate 获取当前速率限制（字节/秒）
func (rl *RateLimiter) GetCurrentRate() int64 {
	return rl.maxBytesPerSecond
}

// IsEnabled 是否启用限速
func (rl *RateLimiter) IsEnabled() bool {
	return rl.enabled
}

// SetRate 动态调整速率限制
//
// 参数：
//   - maxBytesPerSecond: 新的速率限制（字节/秒），0表示禁用限速
func (rl *RateLimiter) SetRate(maxBytesPerSecond int64) {
	if maxBytesPerSecond <= 0 {
		rl.enabled = false
		log.Printf("🚦 禁用速率限制器: %s", rl.name)
		return
	}

	rl.maxBytesPerSecond = maxBytesPerSecond
	rl.limiter.SetLimit(rate.Limit(maxBytesPerSecond))
	rl.limiter.SetBurst(int(maxBytesPerSecond))
	rl.enabled = true

	log.Printf("🚦 更新速率限制器: %s, 新限速=%d bytes/s (%.2f MB/s)",
		rl.name, maxBytesPerSecond, float64(maxBytesPerSecond)/(1024*1024))
}

// ========================================
// 预设配置
// ========================================

// TrafficConfig 流量控制配置
type TrafficConfig struct {
	SmallRequestLimit  int64 // 小请求限速（<1MB），0=不限速
	MediumRequestLimit int64 // 中等请求限速（1-10MB），字节/秒
	LargeRequestLimit  int64 // 大请求限速（>10MB），字节/秒
}

// DefaultTrafficConfig 默认流量控制配置
var DefaultTrafficConfig = TrafficConfig{
	SmallRequestLimit:  0,                // 小请求不限速
	MediumRequestLimit: 10 * 1024 * 1024, // 中等请求：10 MB/s
	LargeRequestLimit:  5 * 1024 * 1024,  // 大请求：5 MB/s
}

// ConservativeTrafficConfig 保守流量控制配置（适合低带宽环境）
var ConservativeTrafficConfig = TrafficConfig{
	SmallRequestLimit:  5 * 1024 * 1024, // 小请求：5 MB/s
	MediumRequestLimit: 3 * 1024 * 1024, // 中等请求：3 MB/s
	LargeRequestLimit:  1 * 1024 * 1024, // 大请求：1 MB/s
}

// AggressiveTrafficConfig 激进流量控制配置（适合高带宽环境）
var AggressiveTrafficConfig = TrafficConfig{
	SmallRequestLimit:  0,                // 小请求不限速
	MediumRequestLimit: 50 * 1024 * 1024, // 中等请求：50 MB/s
	LargeRequestLimit:  20 * 1024 * 1024, // 大请求：20 MB/s
}

// CreateRateLimiterForRequest 根据请求大小创建合适的速率限制器
//
// 参数：
//   - requestSize: 请求大小（字节）
//   - config: 流量控制配置
//
// 返回：
//   - *RateLimiter: 速率限制器（可能不启用限速）
func CreateRateLimiterForRequest(requestSize int64, config TrafficConfig) *RateLimiter {
	var limit int64
	var name string

	if requestSize < 1*1024*1024 {
		// 小请求（<1MB）
		limit = config.SmallRequestLimit
		name = "小请求"
	} else if requestSize < 10*1024*1024 {
		// 中等请求（1-10MB）
		limit = config.MediumRequestLimit
		name = "中等请求"
	} else {
		// 大请求（>10MB）
		limit = config.LargeRequestLimit
		name = "大请求"
	}

	return NewRateLimiter(name, limit)
}

// ========================================
// 限速读写器 (Rate-Limited Reader/Writer)
// ========================================

// ❌ RateLimitedReader/Writer已删除（未使用）
// 保留TokenBucketRateLimiter用于客户端限速
